package cn.com.lib.listview;


import cn.com.lib.R;
import android.content.Context;
import android.graphics.Color;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.view.ViewGroup.LayoutParams;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.Scroller;

/** @author maizi
 * LibRefreshLayoutBase.java
 * 2015年5月19日
 * 可上下滑动  内含空间的父布局
 */
public abstract class LibRefreshLayoutBase<T extends View> extends ViewGroup implements OnScrollListener,IStatus{
	
	/**屏幕高度
	 */
	protected int mScreenHeight; 
	/**屏幕宽度
	 */
	protected int mScreenWidth; 
	/**Header的最大高度
	 */
	protected int mHeaderHeight;
	/**滑动事件
	 */
	protected Scroller mScroller;
	/**内容视图，即用户触摸导致下拉刷新，上拉加载的主视图
	 */
	protected T mContentView;
	/**下拉刷新时显示的header View
	 */
	protected View mHeaderView;
	/**上拉加载时显示的Footer View
	 */
	protected View mFooterView;
	/**滑动过程中Y坐标的偏移量
	 */
	protected int mYOffset;
	/**最后一次触摸事件的y轴坐标
	 */
	protected int mLastY = 0;
	/**
     * 最初的滚动位置.第一次布局时滚动header的高度的距离
     */
    protected int mInitScrollY = 0;
	/**当前状态
	 */
	protected int mCurrentStatus = PULL_STATUS_IDLE;
	 /**
     * 下拉刷新监听器
     */
    protected OnRefreshListener mOnRefreshListener;

	
	
	
	
	public LibRefreshLayoutBase(Context context) {
		this(context,null);
	}
	public LibRefreshLayoutBase(Context context, AttributeSet attrs) {
		this(context, attrs,0);
	}
	public LibRefreshLayoutBase(Context context, AttributeSet attrs,
			int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		mScroller = new Scroller(context);
		mScreenHeight = context.getResources().getDisplayMetrics().heightPixels;
		mScreenWidth = context.getResources().getDisplayMetrics().widthPixels;
		mHeaderHeight = mScreenHeight/4;
		initLayout(context);
	}
	/**初始化整个布局 
	 * @param context
	 */
	private void initLayout(Context context){
		setupHeadererView(context);
		
		setupContentView(context);
		setDefaultContentLayoutParams();
		
		setupFooterView(context);
	}
	
	/**初始化HeaderView
	 *  @param context
	 */
	private void setupHeadererView(Context context) {
		mHeaderView = LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header, this,false);
        mHeaderView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, mHeaderHeight));
        mHeaderView.setBackgroundColor(Color.RED);
        mHeaderView.setPadding(0, mHeaderHeight - 100, 0, 0);
		addView(mHeaderView);
		//#获取Header中的详细控件
	}
	/**初始化ContentView，子类覆盖
	 *  @param context
	 */
	protected abstract void setupContentView(Context context);
	/** 设置Content View的默认布局参数
	 */
	private void setDefaultContentLayoutParams() {
		LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
		mContentView.setLayoutParams(layoutParams);
	}
	/**初始化footer View
	 *  @param context
	 */
	private void setupFooterView(Context context) {
		mFooterView = LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_footer, this, false);
		addView(mFooterView);
	}
    
	/** 与Scroller合作，实现平滑滚动。在该方法中调用Scroller的computeScrollOffset来判断滚动是否结束。
	 * 如果没有结束，滚动到相应的位置，并调用postInvalidate方法重绘界面，然后再次进入到这个computeScroll流程，知道滚动结束
	 */
	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			postInvalidate();
		}
	}
	/**在适当的时候拦截触摸事件，是指在mContentView滑动到顶部，并且是下拉时拦截触摸事件。
	 * 否则不拦截，交给其child view处理
	 *  @param ev
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		int action = ev.getAction();
		if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
			return false;
		}
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			mLastY = (int) ev.getRawY();
			break;
		case MotionEvent.ACTION_MOVE:
			mYOffset = (int) (ev.getRawY() - mLastY);
			if (isTop() && mYOffset > 0) {
				return true;
			}
			break;
		default:
			break;
		}
		return false;
	}
	
	/**是否已经到达最顶部，子类需覆写该方法，使Content View滑动到顶端时返回true。 
	 */
	protected abstract boolean isTop();
	/** 是否到达最底部，子类需覆写该方法，使Content View滑动到最低端时返回true。
	 */
	protected abstract boolean isBottom();
	
	/* 在这里处理触摸事件，以达到下拉刷新或上拉加载的效果
	 * @see android.view.View#onTouchEvent(android.view.MotionEvent)
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			mLastY = (int) event.getRawY();
			break;
		case MotionEvent.ACTION_MOVE:
			int currentY = (int) event.getRawY();
			mYOffset = currentY - mLastY;
			if (mCurrentStatus != PULL_STATUS_LOADING) {
                changeScrollY(mYOffset);
            }
//            rotateHeaderArrow();
//            changeTips();
            mLastY = currentY;
			break;
		case MotionEvent.ACTION_UP:
			// 下拉刷新的具体操作
            doRefresh();
			break;
		default:
			break;
		}
		return true;
	}
	/**
     * 手指抬起时,根据用户下拉的高度来判断是否是有效的下拉刷新操作。如果下拉的距离超过header view的
     * 1/2那么则认为是有效的下拉刷新操作，否则恢复原来的视图状态.
     */
    private void changeHeaderViewStaus() {
        int curScrollY = getScrollY();
        // 超过1/2则认为是有效的下拉刷新, 否则还原
        if (curScrollY < mInitScrollY / 2) {
            mScroller.startScroll(getScrollX(), curScrollY, 0, mHeaderView.getPaddingTop()
                    - curScrollY);
            mCurrentStatus = PULL_STATUS_REFRESHING;
//            mTipsTextView.setText(R.string.pull_to_refresh_refreshing_label);
//            mArrowImageView.clearAnimation();
//            mArrowImageView.setVisibility(View.GONE);
//            mProgressBar.setVisibility(View.VISIBLE);
        } else {
            mScroller.startScroll(getScrollX(), curScrollY, 0, mInitScrollY - curScrollY);
            mCurrentStatus = PULL_STATUS_IDLE;
        }
        invalidate();
    }
	 /**
     * 执行下拉刷新
     */
    protected void doRefresh() {
        changeHeaderViewStaus();
        // 执行刷新操作
        if (mCurrentStatus == PULL_STATUS_REFRESHING && mOnRefreshListener != null) {
            mOnRefreshListener.onRefresh();
        }
    }
	
	/** @param distance
	 */
	protected void changeScrollY(int distance){
		// 最大值为 scrollY(header 隐藏), 最小值为0 ( header 完全显示).
        int curY = getScrollY();
        // 下拉
        if (distance > 0 && curY - distance > getPaddingTop()) {
            scrollBy(0, -distance);
        } else if (distance < 0 && curY - distance <= mInitScrollY) {
            // 上拉过程
            scrollBy(0, -distance);
        }
        curY = getScrollY();
        int slop = mInitScrollY / 2;
        //
        if (curY > 0 && curY < slop) {
            mCurrentStatus = PULL_STATUS_RELEASE_TO_REFRESH;
        } else if (curY > 0 && curY > slop) {
            mCurrentStatus = PULL_STATUS_PULL_TO_REFRESH;
        }
	}
	
	/* 丈量视图的宽、高。宽度为用户设置的宽度，高度则为header, content view, footer这三个子控件的高度只和。
	 * @see android.view.View#onMeasure(int, int)
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int childCount = getChildCount();
        int finalHeight = 0;
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            // measure
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
            // 该view所需要的总高度
            finalHeight += child.getMeasuredHeight();
        }
        setMeasuredDimension(width, finalHeight);
    }
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
        // 用户设置了加载更多监听器，且到了最底部，并且是上拉操作，那么执行加载更多.
//        if (mLoadListener != null && isBottom() && mScroller.getCurrY() <= mInitScrollY
//                && mYOffset <= 0
//                && mCurrentStatus == STATUS_IDLE) {
//            showFooterView();
//            doLoadMore();
//        }
    }
	/* 布局函数，将header, content view,
     * footer这三个view从上到下布局。布局完成后通过Scroller滚动到header的底部，即滚动距离为header的高度 +
     * 本视图的paddingTop，从而达到隐藏header的效果.
	 * @see android.view.ViewGroup#onLayout(boolean, int, int, int, int)
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        int top = getPaddingTop();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            child.layout(0, top, child.getMeasuredWidth(), child.getMeasuredHeight() + top);
            top += child.getMeasuredHeight();
        }
        // 计算初始化滑动的y轴距离
        mInitScrollY = mHeaderView.getMeasuredHeight() + getPaddingTop();
        // 滑动到header view高度的位置, 从而达到隐藏header view的效果
        scrollTo(0, mInitScrollY);
    }
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
	}
	/**设置下拉刷新监听器
     */
    public void setOnRefreshListener(OnRefreshListener listener) {
        mOnRefreshListener = listener;
    }

}
